package com.lulu.gateway;

import cn.hutool.core.util.StrUtil;
import com.lulu.common.model.entity.InterfaceInfo;
import com.lulu.common.service.InnerInterfaceInfoService;
import com.lulu.sdk.client.LuluClient;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.Yaml;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author wlc
 * @version 1.0
 */
@Component
public class MyRouteDefinitionRepository implements RouteDefinitionRepository{

    @DubboReference
    private InnerInterfaceInfoService innerInterfaceInfoService;


    public Flux<RouteDefinition> getRouteDefinitions() {
        //从数据库中读取路由信息
        List<RouteDefinition> routeDefinitions=getRouteConfigs();
//        List<RouteDefinition> routeDefinitions=new ArrayList<>();
        return Flux.fromIterable(routeDefinitions);
    }

    public List<RouteDefinition> getRouteConfigs() {
        List<InterfaceInfo> list = innerInterfaceInfoService.list();
        if (null == list || list.size() <= 0) {
            return Collections.EMPTY_LIST;
        }

        List<RouteDefinition> routeDefinitions = new ArrayList<>();
        for (InterfaceInfo rule : list) {
            RouteDefinition routeDefinition = new RouteDefinition();
            routeDefinition.setId(rule.getRouteId());
            routeDefinition.setUri(URI.create(rule.getRouteUri()));
            routeDefinition.setPredicates(this.getPredicates(rule.getRoutePredicates()));
            routeDefinitions.add(routeDefinition);
        }
        return routeDefinitions;
    }

    private List<PredicateDefinition> getPredicates(String text) {
        if (StrUtil.isBlank(text)) {
            return Collections.EMPTY_LIST;
        }
        Yaml yaml = new Yaml();
        List<String> predicateList = yaml.loadAs(text, List.class);
        List<PredicateDefinition> predicateDefinitions = new ArrayList<>();
        for (String predicate : predicateList) {
            if (StrUtil.isBlank(predicate)) {
                continue;
            }
            PredicateDefinition definition = new PredicateDefinition(predicate);
            predicateDefinitions.add(definition);
        }
        return predicateDefinitions;
    }


    public Mono<Void> save(Mono<RouteDefinition> route) {
        return null;
    }

    public Mono<Void> delete(Mono<String> routeId) {
        return null;
    }
}
